<?php

// Copyright 2020 Catchpoint Systems Inc.
// Use of this source code is governed by the Polyform Shield 1.0.0 license that can be
// found in the LICENSE.md file.
require_once __DIR__ . '/common.inc';

require_once INCLUDES_PATH . '/optimization_detail.inc.php';
require_once INCLUDES_PATH . '/breakdown.inc';
require_once INCLUDES_PATH . '/testStatus.inc';
require_once INCLUDES_PATH . '/common.inc';
require_once INCLUDES_PATH . '/include/TestInfo.php';
require_once INCLUDES_PATH . '/include/TestResults.php';
require_once INCLUDES_PATH . '/include/RunResultHtmlTable.php';
require_once INCLUDES_PATH . '/include/TestResultsHtmlTables.php';

$breakdown = array();
$testComplete = true;
$status = GetTestStatus($id, false);
if ($status['statusCode'] < 200) {
    $testComplete = false;
}
$headless = false;
if (GetSetting('headless')) {
    $headless = true;
}

$testInfo = TestInfo::fromFiles($testPath);
$testResults = TestResults::fromFiles($testInfo);


$testStepResult = TestStepResult::fromFiles($testInfo, $run, $cached, $step);
$requests = $testStepResult->getRequests();

$blockingReqs = array();

foreach ($requests as $request) {
    if ($request['renderBlocking'] === "blocking" && $request['contentType'] === "application/javascript") {
        array_push($blockingReqs, $request['host'] . $request['url']);
    }
}

$page_keywords = array('Results', 'WebPageTest', 'Website Speed Test', 'Page Speed');
$page_description = "Website performance test result$testLabel.";
?>
<!DOCTYPE html>
<html lang="en-us">

<head>
    <title><?php echo "$page_title - WebPageTest Result"; ?></title>
    <script>
        document.documentElement.classList.add('has-js');
    </script>
    <style>
        tr.stepResultRow.jkActive td.resultCell {
            border-left: 2px #181741 solid;
        }

        td.separation {
            height: 2em;
        }
    </style>
    <?php if (!$testComplete) {
        $autoRefresh = true;
    ?>
        <noscript>
            <meta http-equiv="refresh" content="30" />
        </noscript>
    <?php }
    $useScreenshot = true;
    $socialTitle = "WebPageTest Performance Test Results";
    $socialDesc = "Check out these web performance test results on WebPageTest.org: ";
    ?>
    <?php include('head.inc'); ?>

</head>

<body class="result result-summary <?php if ($req_screenshot) {
                                        echo ' screenshot';
                                    } ?>">
    <?php
    $tab = 'Test Result';
    $subtab = 'Performance Summary';
    include 'header.inc';
    ?>


    <div class="results_main_contain">
        <div class="results_main">

            <?php
            if (!$testComplete) {
            ?>
                <p class="left">
                    <?php
                    if (GetSetting('nolinks')) {
                        echo "URL: $url<br>\n";
                    } else {
                        echo "URL: <a rel=\"nofollow\" href=\"$url\">$url</a><br>\n";
                    }
                    echo "From: {$test['test']['location']}<br>\n";
                    echo GetTestInfoHtml();
                    ?>
                </p>
            <?php
                $expected = $test['test']['runs'];
                $available = $testResults->countRuns();
                echo "<h3>Test is partially complete ($available of $expected tests).<br>This page will refresh as tests complete.</h3>";
                echo "<script>\n";
                echo "var availableTests=$available;\n";
                echo "</script>\n";
            } else {
            ?>
                <div class="results_and_command">
                    <div class="results_header">
                        <h2>Performance Summary</h2>
                        <div class="summary_opps">
                            <?php
                            include INCLUDES_PATH . '/experiments/common.inc';
                            include INCLUDES_PATH . '/experiments/summary.inc';

                            ?>
                            <?php if (!isset($experiments_paid) || !$experiments_paid) { ?>
                                <p><span class="opportunities_summary_exps">You have Free Experiments Available!
                                        <?php
                                        if ($tabs && $tabs['Opportunities & Experiments']) {
                                            echo '<a href="' . $tabs['Opportunities & Experiments'] . '">Try them now!</a>';
                                        }
                                        ?></span></p>
                            <?php } ?>
                        </div>
                    </div>
                </div>

                <div id="result" class="results_body">
                    <div id="average">
                        <?php
                        $is_test_error = $testInfo->isTestError();
                        $fvRunResults = $testResults->getRunResult($fvMedian, false);
                        $rvRunResults = $rvMedian ? $testResults->getRunResult($rvMedian, true) : null;

                        if ($fvMedian) {
                            echo '<h3 class="hed_sub">Page Performance Metrics ';
                            $medianMetrics = array(
                                "chromeUserTiming.CumulativeLayoutShift" => "Cumulative Layout Shift",
                                "firstContentfulPaint" => "First Contentful Paint",
                                "chromeUserTiming.LargestContentfulPaint" => "Largest Contentful Paint",
                                "fullyLoaded" => "Load Time",
                                "SpeedIndex" => "Speed Index",
                                "render" => "Start Render",
                                "TTFB" => "Time to First Byte",
                                "TotalBlockingTime" => "Total Blocking Time"
                            );
                            if ($medianMetrics[$median_metric]) {
                                $friendlyMedianMetric = $medianMetrics[$median_metric];
                            } else {
                                $friendlyMedianMetric = htmlspecialchars($median_metric);
                            }
                            if ($testResults->countRuns() > 1) {
                                echo '<em>(Based on Median Run by:
                          <details><summary>' . $friendlyMedianMetric . '</summary>';
                                echo "<ul>";

                                $url = strtok($_SERVER["REQUEST_URI"], '?');
                                foreach ($medianMetrics as $key => $value) {
                                    if ($pageData[$run][$cached][$key]) {
                                        echo "<li><a href='" . $url . "?test=$id&medianMetric=" . $key . "'>" . $value . "</a></li>";
                                    }
                                }
                                echo "</ul>";


                                echo '</details>)</em>';
                            }
                            echo '</h3>';

                            echo '<details class="metrics_shown">
                          <summary><strong>Note:</strong> Metric availability will vary</summary>
                          <p><strong>Please note:</strong> Availability of metrics will vary based on the browser being tested. Also, the way a site performs in some conditions may not predict how well it will perform in others, so we encourage testing in a variety of browsers, devices, & locations.</p>
                          </details>';

                            $resultTable = new RunResultHtmlTable($testInfo, $fvRunResults, $rvRunResults, false, true);
                            $resultTable->useLabelLinks(true);
                            $resultTable->disableColumns(array(
                                RunResultHtmlTable::COL_VISUAL_COMPLETE,
                                RunResultHtmlTable::COL_COST,
                                RunResultHtmlTable::COL_FULLYLOADED,
                                RunResultHtmlTable::COL_REQUESTS,
                                RunResultHtmlTable::COL_RESULT,
                            ));
                            $resultTable->disableCustomMetrics();
                            if (GetSetting('show_cost')) {
                                //$resultTable->enableColumns(array(RunResultHtmlTable::COL_COST));
                            }
                            echo $resultTable->create(true);

                            if ($testResults->countRuns() > 1) {
                                $link = '/video/compare.php?tests=';
                                $repeatlink = '/video/compare.php?tests=';
                                $cnt = 1;
                                do {
                                    $link .= $id . '-r:' . $cnt;
                                    $repeatlink .= $id . '-r:' . $cnt . '-c:1';
                                    if ($tests[0]['step']) {
                                        $link .= '-s:' . $test['step'];
                                        $repeatlink .= '-s:' . $test['step'];
                                    }
                                    $link .= ',';
                                    $repeatlink .= ',';
                                    $cnt++;
                                } while ($cnt <= $testResults->countRuns());
                                $link = substr($link, 0, -1) . ($req_fp ? "&fp=$req_fp" : '');
                                $repeatlink = substr($repeatlink, 0, -1) . ($req_fp ? "&fp=$req_fp" : '');
                                echo "<a href=\"" . $link . "\" class=\"result_plot\">Compare First Views</a>";
                                if ($rvRunResults) {
                                    echo "<a href=\"" . $repeatlink . "\" class=\"result_plot\">Compare Repeat Views</a>";
                                }
                                $graphLink = "graph_page_data.php?tests=$id&medianMetric=$median_metric" . ($req_fp ? "&fp=$req_fp" : '');

                                echo "<a href='$graphLink' class='result_plot'>Plot Full Results</a>";
                            }
                        ?>
                        <?php
                        } // fvMedian
                        if (!$fvMedian || $is_test_error) {
                            $error = 'The test completed but there were no successful results.';
                            $detail = null;
                            if ($is_test_error) {
                                $error = 'The test failed to run.';
                                $detail = $test['testinfo']['test_error'];
                            } elseif (
                                array_key_exists('testinfo', $test) &&
                                array_key_exists('errors', $test['testinfo'])
                            ) {
                                // just grab the first error we find from an individual run
                                foreach ($test['testinfo']['errors'] as &$error_run) {
                                    foreach ($error_run as &$error_str) {
                                        if (strlen($error_str)) {
                                            $error = 'The testing completed but failed.';
                                            $detail = $error_str;
                                            break 2;
                                        }
                                    }
                                }
                            }
                            if (!$fvMedian) {
                                echo '<h3>' . htmlspecialchars($error) . '</h3>';
                            }
                            if (isset($detail)) {
                                echo '<h4>' . htmlspecialchars($detail) . '</h4>';
                            }
                        }
                        ?>
                    </div>

                    <?php
                    if (isset($fvRunResults)) {
                        echo '<div class="cruxembed">';
                        require_once(INCLUDES_PATH . '/include/CrUX.php');
                        InsertCruxHTML($fvRunResults);
                        echo '</div>';
                    }
                    ?>
                <?php } ?>
                <div id="tables" style="text-align:left;">
                    <h3 class="hed_sub">Individual Runs</h3>
                    <?php
                    $tcpDumpView = GetSetting('tcpdump_view') ? GetSetting('tcpdump_view') : null;
                    $resultTables = new TestResultsHtmlTables($testInfo, $testResults, $testComplete, $median_metric, $tcpDumpView);
                    echo $resultTables->create();
                    ?>
                </div>
                </div>
                <?php include(INCLUDES_PATH . '/cta-banner.inc'); ?>
        </div>

        <?php include('footer.inc'); ?>
    </div>
    <script src="/assets/js/jk-navigation.js"></script>
    <script>
        addJKNavigation("tr.stepResultRow");
    </script>
    <?php
    $breakdown = $resultTables->getBreakdown();
    if ($breakdown) {
    ?>
        <script src="//www.google.com/jsapi"></script>
        <script>
            <?php
            echo 'var wptBreakdown=' . json_encode($breakdown) . ";\n";
            ?>

            google.load("visualization", "1", {
                packages: ["corechart"]
            });
            google.setOnLoadCallback(drawCharts);

            function RGBtoHex(R, G, B) {
                return toHex(R) + toHex(G) + toHex(B)
            }

            function toHex(N) {
                if (N == null) return "00";
                N = parseInt(N);
                if (N == 0 || isNaN(N)) return "00";
                N = Math.max(0, N);
                N = Math.min(N, 255);
                N = Math.round(N);
                return "0123456789ABCDEF".charAt((N - N % 16) / 16) +
                    "0123456789ABCDEF".charAt(N % 16);
            }

            function drawCharts() {
                for (index in wptBreakdown) {
                    var bytes = new google.visualization.DataTable();
                    bytes.addColumn('string', 'Content Type');
                    bytes.addColumn('number', 'Bytes');
                    var bytesColors = new Array();
                    for (i in wptBreakdown[index].data) {
                        bytes.addRow([i, wptBreakdown[index].data[i].bytes]);
                        var color = RGBtoHex(wptBreakdown[index].data[i].color[0], wptBreakdown[index].data[i].color[1], wptBreakdown[index].data[i].color[2]);
                        bytesColors.push('#' + color);
                    }
                    var bytesOptions = {
                        width: 370,
                        height: 200,
                        title: 'Bytes',
                        colors: bytesColors
                    };
                    var bytesChart = new google.visualization.PieChart(document.getElementById('bytes_' + wptBreakdown[index].run));
                    bytesChart.draw(bytes, bytesOptions);

                    var requests = new google.visualization.DataTable();
                    requests.addColumn('string', 'Content Type');
                    requests.addColumn('number', 'Requests');
                    var requestsColors = new Array();
                    for (i in wptBreakdown[index].data) {
                        requests.addRow([i, wptBreakdown[index].data[i].requests]);
                        var color = RGBtoHex(wptBreakdown[index].data[i].color[0], wptBreakdown[index].data[i].color[1], wptBreakdown[index].data[i].color[2]);
                        requestsColors.push('#' + color);
                    }
                    var requestsOptions = {
                        width: 370,
                        height: 200,
                        title: 'Requests',
                        colors: requestsColors
                    };
                    var requestsChart = new google.visualization.PieChart(document.getElementById('requests_' + wptBreakdown[index].run));
                    requestsChart.draw(requests, requestsOptions);
                }
            }
        </script>
    <?php
    } // $breakdown

    if (!$testComplete) {
        echo "<script>\n";
        echo "var testId = '$id';\n";
    ?>
        // polyfill performance.now
        if ("performance" in window == false) {
        window.performance = {};
        }
        Date.now = (Date.now || function () { // thanks IE8
        return new Date().getTime();
        });
        if ("now" in window.performance == false){
        var nowOffset = Date.now();
        if (performance.timing && performance.timing.navigationStart){
        nowOffset = performance.timing.navigationStart
        }
        window.performance.now = function now(){
        return Date.now() - nowOffset;
        }
        }
        var lastUpdate = window.performance.now();
        function UpdateStatus(){
        var now = window.performance.now();
        var elapsed = now - lastUpdate;
        lastUpdate = now;
        if (elapsed < 0 || elapsed> 10000) {
            try {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', '/testStatus.php?f=json&pos=1&test=' + testId, true);
            xhr.onreadystatechange = function() {
            if (xhr.readyState != 4)
            return;
            var reload = false;
            if (xhr.status == 200) {
            var response = JSON.parse(xhr.responseText);
            if (response['statusCode'] != undefined) {
            if (response['statusCode'] == 100) {
            if (response['data'] != undefined &&
            availableTests != undefined &&
            response.data['testsCompleted'] != undefined &&
            response.data['testsCompleted'] > availableTests)
            reload = true;
            } else
            reload = true;
            }
            }
            if (reload) {
            window.location.reload(true);
            } else {
            setTimeout('UpdateStatus()', 15000);
            }
            };
            xhr.onerror = function() {
            setTimeout('UpdateStatus()', 15000);
            };
            xhr.send();
            } catch (err) {
            setTimeout('UpdateStatus()', 15000);
            }
            } else {
            setTimeout('UpdateStatus()', 15000);
            }
            }
            setTimeout('UpdateStatus()', 15000);
            </script>
        <?php
    }
        ?>
</body>

</html>